# 需要的常量
# 寄存器编号
MSR = 1
MAR = 2
MDR = 3
RAM = 4
IR = 5
DST = 6
SRC = 7
A = 8
B = 9
C = 10
D = 11
DI = 12
SI = 13
SP = 14
BP = 15
CS = 16
DS = 17
SS = 18
ES = 19
VEC = 20
T1 = 21
T2 = 22

# 寄存器输出到BUS
MSR_OUT = MSR
MAR_OUT = MAR
MDR_OUT = MDR
RAM_OUT = RAM
IR_OUT = IR
DST_OUT = DST
SRC_OUT = SRC
A_OUT = A
B_OUT = B
C_OUT = C
D_OUT = D
DI_OUT = DI
SI_OUT = SI
SP_OUT = SP
BP_OUT = BP
CS_OUT = CS
DS_OUT = DS
SS_OUT = SS
ES_OUT = ES
VEC_OUT = VEC
T1_OUT = T1
T2_OUT = T2

# BUS写入到寄存器
_SHIFT = 5
MSR_IN = MSR << _SHIFT
MAR_IN = MAR << _SHIFT
MDR_IN = MDR << _SHIFT
RAM_IN = RAM << _SHIFT
IR_IN = IR << _SHIFT
DST_IN = DST << _SHIFT
SRC_IN = SRC << _SHIFT
A_IN = A << _SHIFT
B_IN = B << _SHIFT
C_IN = C << _SHIFT
D_IN = D << _SHIFT
DI_IN = DI << _SHIFT
SI_IN = SI << _SHIFT
SP_IN = SP << _SHIFT
BP_IN = BP << _SHIFT
CS_IN = CS << _SHIFT
DS_IN = DS << _SHIFT
SS_IN = SS << _SHIFT
ES_IN = ES << _SHIFT
VEC_IN = VEC << _SHIFT
T1_IN = T1 << _SHIFT
T2_IN = T2 << _SHIFT

# 源操作数读写
SRC_R = 2 ** 10
SRC_W = 2 ** 11
# 目标操作数读写
DST_R = 2 ** 12
DST_W = 2 ** 13

# PC
PC_WE = 2 ** 14
PC_CS = 2 ** 15
PC_EN = 2 ** 16
PC_OUT = PC_CS
PC_IN = PC_WE | PC_CS
PC_INC = PC_WE | PC_EN | PC_CS


# ALU = 2 ** 20
# _OP_0 = 17
# _OP_1 = 18
# _OP_2 = 19
# ALU_OUT = ALU
# OP_ADD = (0 << _OP_0)  # 0 默认就是加法
# OP_SUB = (1 << _OP_0)  # OP=001
# OP_INC = ALU | (1 << _OP_1)  # OP=010
# OP_DEC = ALU | (1 << _OP_1) | (1 << _OP_0)  # OP=011
# OP_AND = ALU | (1 << _OP_2)  # OP=100
# OP_OR = ALU | (1 << _OP_2) | (1 << _OP_0)  # OP=101
# OP_XOR = ALU | (1 << _OP_2) | (1 << _OP_1)  # OP=110
# OP_NOT = ALU | (1 << _OP_2) | (1 << _OP_1) | (1 << _OP_0)  # OP=111

# OP
_OP_SHIFT = 17

OP_ADD = 0
OP_SUB = 1 << _OP_SHIFT
OP_INC = 2 << _OP_SHIFT
OP_DEC = 3 << _OP_SHIFT
OP_AND = 4 << _OP_SHIFT
OP_OR = 5 << _OP_SHIFT
OP_XOR = 6 << _OP_SHIFT
OP_NOT = 7 << _OP_SHIFT

# ALU的4位
ALU_OUT = 1 << 20
ALU_PSW = 1 << 21
# 中断位写
ALU_INT_W = 1 << 22
# 中断有效位
ALU_INT = 1 << 23

# 开启中断
ALU_STI = ALU_INT_W
# 关闭中断
ALU_CLI = ALU_INT_W | ALU_INT

# 停止
HLT = 2 ** 31
# 指令周期
CYC = 2 ** 30

# 指令标志
# 2地址指令 1000 0000
ADDR2 = 1 << 7
# 1地址指令 0100 0000
ADDR1 = 1 << 6

ADDR2_SHIFT = 4
ADDR1_SHIFT = 2

# 立即寻址
AM_INS = 0
# 寄存器寻址
AM_REG = 1
# 直接寻址
AM_DIR = 2
# 内存寻址
AM_RAM = 3


